


import java.util.Scanner;

public class MemoryFitSimulation {
    static class FreeMemArea {
        int address;
        int size;
        int end;
    }
    public static void main(String[] args) {
        FreeMemArea[] freeMemAreas = new FreeMemArea[100];
        FreeMemArea currentFreeMemArea = new FreeMemArea();
        Scanner scanner = new Scanner(System.in);
        System.out.println(" input address and size");
        currentFreeMemArea.address = scanner.nextInt();
        currentFreeMemArea.size = scanner.nextInt();

        int endLocation = currentFreeMemArea.address + currentFreeMemArea.size - 1;
        int OccupiedCount = 1;
        freeMemAreas[0] = currentFreeMemArea;
        for (int i = 0; i < OccupiedCount; i++) {
            freeMemAreas[i].end = freeMemAreas[i].address + freeMemAreas[i].size - 1;
        }
        System.out.println(" Index   *       adr    *      end      *       size");
        for (int i = 0; i < OccupiedCount; i++) {
            System.out.println(" " + (i + 1) + "               " + freeMemAreas[i].address + "             " + freeMemAreas[i].end + "             " + freeMemAreas[i].size);
        }
        int y;
        for (y = 0; y < 1; y++) {
            System.out.print("input    the  way (best  or  first):");
            String allocMethod = scanner.next();
            if (allocMethod.equals("best")) {
                while (true) {
                    int newSuccess = 1;
                    System.out.print("Assign  or  Accept:");
                    String actionChoice = scanner.next();
                    if (actionChoice.equals("ac")) {
                        System.out.print("Input  adr  and  size: ");
                        int address = scanner.nextInt();
                        int size = scanner.nextInt();
                        int z = 0, v = 0;
                        if (OccupiedCount == 0) {
                            FreeMemArea freeMemArea = new FreeMemArea();
                            freeMemArea.address = address;
                            freeMemArea.size = size;
                            freeMemAreas[OccupiedCount] = freeMemArea;
                            OccupiedCount++;
                            newSuccess = 0;
                        }
                        for (int i = 0; i < OccupiedCount; i++) {

                            if (address == (freeMemAreas[i].address + freeMemAreas[i].size)) {
                                int x = 0;
                                for (int o = 0; o < OccupiedCount; o++) {
                                    if ((address + size) != freeMemAreas[o].address) {
                                        x++;
                                    } else {
                                        freeMemAreas[i].size = freeMemAreas[i].size + size + freeMemAreas[o].size;
                                        for (int p = o; p < OccupiedCount - 1; p++) {
                                            freeMemAreas[p] = freeMemAreas[p + 1];
                                        }
                                        OccupiedCount--;
                                        break;
                                    }
                                    if (x == OccupiedCount) {
                                        freeMemAreas[i].size = freeMemAreas[i].size + size;
                                    }
                                }

                                break;
                            } else if ((address >= freeMemAreas[i].address && address <= freeMemAreas[i].end) || ((address + size) > freeMemAreas[i].address && (address + size) <= freeMemAreas[i].end) || (address <= freeMemAreas[i].address && (address + size) > freeMemAreas[i].end)) {
                                System.out.println("重复了");
                                break;
                            } else if ((address + size) > endLocation) {
                                System.out.println("越界");
                                break;
                            } else if (address < 0) {
                                System.out.println("首地址为负");
                                break;
                            } else {
                                z++;

                            }
                            if (address + size == freeMemAreas[i].address) {
                                for (int o = 0; o < OccupiedCount; o++) {
                                    if (address != (freeMemAreas[o].address + freeMemAreas[o].size)) {
                                        freeMemAreas[i].address = address;
                                        freeMemAreas[i].size = size + freeMemAreas[i].size;
                                        break;
                                    }
                                }
                                break;
                            } else {
                                v++;

                            }

                            if (z == OccupiedCount && v == OccupiedCount && newSuccess != 0) {
                                FreeMemArea r = new FreeMemArea();
                                r.address = address;
                                r.size = size;
                                freeMemAreas[OccupiedCount] = r;
                                OccupiedCount++;
                                break;
                            }
                        }
                    } else if (actionChoice.equals("as")) {
                        System.out.print("input APPLACATION:  ");
                        int f = scanner.nextInt();
                        int number = 0;
                        for (int i = 0; i < OccupiedCount; i++) {

                            if (f <= freeMemAreas[i].size) {
                                freeMemAreas[i].size = freeMemAreas[i].size - f;
                                freeMemAreas[i].end = freeMemAreas[i].end - f;
                                System.out.println("SUCCESS!!!  ADDRESS=" + (freeMemAreas[i].end + 1));
                                break;
                            } else {
                                number++;
                            }
                        }
                        if (number == OccupiedCount) {
                            System.out.println("Too   large  application!");

                        }
                    } else {
                        System.out.println("input mistake");
                        continue;
                    }
                    for (int i = 0; i < OccupiedCount; i++) {
                        for (int j = 0; j < OccupiedCount; j++) {
                            if (freeMemAreas[i].address == (freeMemAreas[j].end + 1) && j != i) {
                                freeMemAreas[j].size = freeMemAreas[i].size + freeMemAreas[j].size;
                                for (int x = i; x < OccupiedCount - 1; x++) {
                                    freeMemAreas[x] = freeMemAreas[x + 1];
                                }
                                OccupiedCount--;
                            }

                        }
                    }
                    for (int i = 0; i < OccupiedCount; i++) {
                        for (int j = i; j < OccupiedCount; j++) {
                            if (freeMemAreas[i].size > freeMemAreas[j].size) {
                                FreeMemArea x = new FreeMemArea();
                                x = freeMemAreas[i];
                                freeMemAreas[i] = freeMemAreas[j];
                                freeMemAreas[j] = x;
                            }
                        }
                    }
                    for (int i = 0; i < OccupiedCount; i++) {
                        freeMemAreas[i].end = freeMemAreas[i].address + freeMemAreas[i].size - 1;
                        if (freeMemAreas[i].end == -1) {
                            freeMemAreas[i].end = 0;

                        }
                        if (freeMemAreas[i].size == 0) {
                            for (int x = i; x < OccupiedCount - 1; x++) {
                                freeMemAreas[x] = freeMemAreas[x + 1];
                            }
                            OccupiedCount--;
                        }
                    }
                    System.out.println(" Index   *       adr    *      end      *       size");
                    for (int i = 0; i < OccupiedCount; i++) {
                        System.out.println(" " + (i + 1) + "               " + freeMemAreas[i].address + "             " + freeMemAreas[i].end + "             " + freeMemAreas[i].size);
                    }

                }

            } else if (allocMethod.equals("first")) {
                while (true) {
                    int u = 1;
                    System.out.print("Assign  or  Accept:");
                    String e = scanner.next();
                    if (e.equals("ac")) {
                        System.out.print("Input  adr  and  size: ");
                        int address = scanner.nextInt();
                        int size = scanner.nextInt();
                        int z = 0, v = 0;
                        if (OccupiedCount == 0) {
                            FreeMemArea r = new FreeMemArea();
                            r.address = address;
                            r.size = size;
                            freeMemAreas[OccupiedCount] = r;
                            OccupiedCount++;
                            u = 0;
                        }
                        for (int i = 0; i < OccupiedCount; i++) {
                            if (address == (freeMemAreas[i].address + freeMemAreas[i].size)) {
                                int x = 0;
                                for (int o = 0; o < OccupiedCount; o++) {
                                    if ((address + size) != freeMemAreas[o].address) {
                                        // freeMemAreas[i].size = freeMemAreas[i].size + size;
                                        x++;
                                    } else {
                                        freeMemAreas[i].size = freeMemAreas[i].size + size + freeMemAreas[o].size;
                                        for (int p = o; p < OccupiedCount - 1; p++) {
                                            freeMemAreas[p] = freeMemAreas[p + 1];
                                        }
                                        OccupiedCount--;
                                        break;
                                    }
                                    if (x == OccupiedCount) {
                                        freeMemAreas[i].size = freeMemAreas[i].size + size;
                                    }
                                }
                                break;
                            } else if ((address >= freeMemAreas[i].address && address <= freeMemAreas[i].end) || ((address + size) > freeMemAreas[i].address && (address + size) <= freeMemAreas[i].end) || (address <= freeMemAreas[i].address && (address + size) > freeMemAreas[i].end)) {
                                System.out.println("重复了");
                                break;
                            } else if ((address + size) > endLocation) {
                                System.out.println("越界");
                                break;
                            } else if (address < 0) {
                                System.out.println("首地址为负");
                                break;
                            } else {
                                z++;
                            }
                            if (address + size == freeMemAreas[i].address) {
                                for (int o = 0; o < OccupiedCount; o++) {
                                    if (address != (freeMemAreas[o].address + freeMemAreas[o].size)) {
                                        freeMemAreas[i].address = address;
                                        freeMemAreas[i].size = size + freeMemAreas[i].size;
                                        break;
                                    }
                                }
                                break;
                            } else {
                                v++;
                            }
                            if (z == OccupiedCount && v == OccupiedCount && u != 0) {
                                FreeMemArea r = new FreeMemArea();
                                r.address = address;
                                r.size = size;
                                freeMemAreas[OccupiedCount] = r;
                                OccupiedCount++;
                                break;
                            }
                        }
                    } else if (e.equals("as")) {
                        System.out.print("input APPLACATION:  ");
                        int f = scanner.nextInt();
                        int number = 0;
                        for (int i = 0; i < OccupiedCount; i++) {
                            if (f <= freeMemAreas[i].size) {
                                freeMemAreas[i].size = freeMemAreas[i].size - f;
                                freeMemAreas[i].end = freeMemAreas[i].end - f;
                                System.out.println("SUCCESS!!!  ADDRESS=" + (freeMemAreas[i].end + 1));
                                break;
                            } else {
                                number++;
                            }
                        }
                        if (number == OccupiedCount) {
                            System.out.println("Too   large  application!");
                        }
                    } else {
                        System.out.println("input mistake");
                        continue;
                    }
                    for (int i = 0; i < OccupiedCount; i++) {
                        for (int j = 0; j < OccupiedCount; j++) {
                            if (freeMemAreas[i].address == (freeMemAreas[j].end + 1) && j != i) {
                                freeMemAreas[j].size = freeMemAreas[i].size + freeMemAreas[j].size;
                                for (int x = i; x < OccupiedCount - 1; x++) {
                                    freeMemAreas[x] = freeMemAreas[x + 1];
                                }
                                OccupiedCount--;
                            }
                        }
                    }
                    for (int i = 0; i < OccupiedCount; i++) {
                        freeMemAreas[i].end = freeMemAreas[i].address + freeMemAreas[i].size - 1;
                        if (freeMemAreas[i].end == -1) {
                            freeMemAreas[i].end = 0;

                        }
                        if (freeMemAreas[i].size == 0) {
                            for (int x = i; x < OccupiedCount - 1; x++) {
                                freeMemAreas[x] = freeMemAreas[x + 1];
                            }
                            OccupiedCount--;
                        }
                    }


                    System.out.println(" Index   *       adr    *      end      *       size");
                    for (int i = 0; i < OccupiedCount; i++) {
                        System.out.println(" " + (i + 1) + "               " + freeMemAreas[i].address + "             " + freeMemAreas[i].end + "             " + freeMemAreas[i].size);
                    }

                }
            } else {
                y--;
                System.out.println("input mistake");
            }
        }
    }
}
